﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Iot.Shared.Enums;
using Iot.Shared.EventBusSend;
using Iot.Shared.Path;
using Iot.TimingDatabase.Helper;
using Iot.TimingDatabase.Models;
using Mediator;
using Microsoft.Extensions.Logging;

namespace Iot.TimingDatabase.Event;

/// <summary>
///     设备模块数据分发到数据总线
/// </summary>
/// <param name="send"></param>
/// <param name="logger"></param>
public sealed class DeviceModuleDataToBusEvent(
    IEventBusSend send,
    ILogger<DeviceModuleDataToBusEvent> logger)
    : INotificationHandler<DeviceModule>
{
    /// <summary>
    ///     日志记录器
    /// </summary>
    private readonly ILogger<DeviceModuleDataToBusEvent> _logger = logger;

    /// <summary>
    ///     实现INotificationHandler接口的Handle方法，用于处理设备模块的通知
    /// </summary>
    /// <param name="notification"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public async ValueTask Handle(DeviceModule notification, CancellationToken cancellationToken)
    {
        try
        {
            _logger.LogTrace("设备模块数据分发到数据总线，设备模块为：{notification}", notification);
            // 获取设备模块的扩展值
            var data = notification.GetExtendedValues();
            _logger.LogTrace("设备模块数据分发到数据总线，设备模块为：{notification},数据为：{data}", notification, data);
            // 将设备模块数据分发到数据总线
            await DistributeDataToBusModel(notification, data);
        }
        catch (Exception e)
        {
            _logger.LogError(e, "设备模块数据分发到数据总线失败，设备模块为：{notification}", notification);
        }
    }


    /// <summary>
    ///     分发空数据
    /// </summary>
    /// <param name="path"></param>
    /// <param name="value"></param>
    /// <param name="timeStamp"></param>
    /// <returns></returns>
    private ValueTask DistributeNullData(DevicePath path, object value, DateTimeOffset? timeStamp = null)
    {
        ArgumentNullException.ThrowIfNull(value);
        switch (value) // 根据value的类型进行不同的处理
        {
            case byte or ushort or short or int or long or uint: // 如果value是byte、ushort、short、int、long、uint类型
                // 发送整型数据
                return send.SendIntegerAsync(path, null, timeStamp);

            case float or double: // 如果value是float、double类型
                // 发送浮点型数据  
                return send.SendFloatAsync(path, null, timeStamp);

            case Switching: // 如果value是Switching类型

                // 发送开关型数据
                return send.SendSwitchingAsync(path, null, timeStamp);

            case Enum: // 如果value是Enum类型

                // 发送枚举型数据
                return send.SendEnumAsync(path, null, timeStamp);
            default:
                _logger.LogInformation("未处理的数据类型，路径为：{path},属性类型为：{type},属性值为：{value}", path, value.GetType(), value);
                break;
        }

        return ValueTask.CompletedTask;
    }


    /// <summary>
    ///     数据分发到数据总线
    /// </summary>
    /// <param name="data"></param>
    /// <param name="values"></param>
    /// <returns></returns>
    private async ValueTask DistributeDataToBusModel(DeviceModule data,
        IReadOnlyList<ExtendedValue> values)
    {
        _logger.LogTrace("数据分发到数据总线，类型为：{data},值为：{values}", data, values);
        // 遍历infos中的每个item
        foreach (var item in values)
        {
            var path = data.Path.Creation(item.Name);
            switch (item.Value) // 根据value的类型进行不同的处理
            {
                case byte or ushort or short or int or long or uint: // 如果value是byte、ushort、short、int、long、uint类型
                    // 发送整型数据
                    await send.SendIntegerAsync(path, Convert.ToInt64(item.Value),
                        data.TimeStamp);
                    break;

                case float or double: // 如果value是float、double类型
                    // 发送浮点型数据  
                    await send.SendFloatAsync(path, Convert.ToDouble(item.Value),
                        data.TimeStamp);
                    break;

                case Switching switching: // 如果value是Switching类型
                    // 发送开关型数据
                    await send.SendSwitchingAsync(path, switching, data.TimeStamp);
                    break;

                case Enum enumValue: // 如果value是Enum类型
                    // 发送枚举型数据
                    await send.SendEnumAsync(path, enumValue, data.TimeStamp);
                    break;
                case null: // 如果value是null
                    // 分发null数据
                    await DistributeNullData(path, item.Default, data.TimeStamp);
                    break;
                default:
                    _logger.LogInformation("未处理的数据类型，类型为：{data},属性值为：{item}", data, item);
                    break;
            }
        }
    }
}